package com.xiang.utils;

import com.xiang.config.EsConfig;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.Operator;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;

/**
 * match查询
 *
 * @author xiangtianlei@gogpay.cn
 * @date 2023-01-29
 */
public class MatchQuery {
    RestHighLevelClient client = EsConfig.getClient();
    Logger logger = LoggerFactory.getLogger(TermQuery.class);

    /**
     * matchAll查询
     */
    @Test
    public void matchAllQuery() throws IOException {
        SearchRequest searchRequest = new SearchRequest(EsConfig.INDEX_NAME);
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.from(0);
        sourceBuilder.size(50);
        sourceBuilder.query(QueryBuilders.matchAllQuery());
        searchRequest.source(sourceBuilder);
        SearchResponse search = client.search(searchRequest, RequestOptions.DEFAULT);
        logger.info("查询语句：{}", searchRequest.source().toString());
        for (SearchHit hit : search.getHits().getHits()) {
            logger.info("查询结果：{}", hit.getSourceAsMap());
        }
    }

    /**
     * match 查询
     */
    @Test
    public void matchQuery() throws IOException {
        SearchRequest request = new SearchRequest(EsConfig.INDEX_NAME);
        SearchSourceBuilder searchBuilder = new SearchSourceBuilder();
        searchBuilder.from(0);
        searchBuilder.size(40);
        searchBuilder.query(QueryBuilders.matchQuery("name.keyword", "张三"));
        request.source(searchBuilder);
        SearchResponse res = client.search(request, RequestOptions.DEFAULT);
        logger.info("查询语句：{}", request.source().toString());
        for (SearchHit hit : res.getHits().getHits()) {
            logger.info("查询结果：{}", hit.getSourceAsMap());
        }
    }

    /**
     * And布尔match查询
     */
    @Test
    public void booleanAndMatchQuery() throws IOException {
        SearchRequest request = new SearchRequest(EsConfig.INDEX_NAME);
        SearchSourceBuilder searchBuilder = new SearchSourceBuilder();
        searchBuilder.from(0);
        searchBuilder.size(40);
        searchBuilder.query(QueryBuilders.matchQuery("name", "张三 1").operator(Operator.AND));
        request.source(searchBuilder);
        SearchResponse res = client.search(request, RequestOptions.DEFAULT);
        logger.info("查询语句：{}", request.source().toString());
        for (SearchHit hit : res.getHits().getHits()) {
            logger.info("查询结果：{}", hit.getSourceAsMap());
        }
    }

    /**
     * OR布尔match查询
     */
    @Test
    public void booleanOrMatchQuery() throws IOException {
        SearchRequest request = new SearchRequest(EsConfig.INDEX_NAME);
        SearchSourceBuilder searchBuilder = new SearchSourceBuilder();
        searchBuilder.from(0);
        searchBuilder.size(40);
        searchBuilder.query(QueryBuilders.matchQuery("name", "张三 1").operator(Operator.OR));
        request.source(searchBuilder);
        SearchResponse res = client.search(request, RequestOptions.DEFAULT);
        logger.info("查询语句：{}", request.source().toString());
        for (SearchHit hit : res.getHits().getHits()) {
            logger.info("查询结果：{}", hit.getSourceAsMap());
        }
    }

    /**
     * 多字段匹配查询
     */
    @Test
    public void multiMatchQuery() throws IOException {
        // 请求request
        SearchRequest request = new SearchRequest(EsConfig.INDEX_NAME);
        // 封装查询
        SearchSourceBuilder builder = new SearchSourceBuilder();
        // mulit_match针对多个Field进行检索,指定的字段会进行分词，精确查找则添加.keyworld
        // 没有keyword,则现将张男分词为张和男，在去模糊倒排索引中查询对应的文档
        // builder.query(QueryBuilders.multiMatchQuery("张男", "name.keyword", "address"));
        builder.query(QueryBuilders.multiMatchQuery("张男", "name", "address"));
        request.source(builder);
        // 请求查询
        SearchResponse res = client.search(request, RequestOptions.DEFAULT);
        for (SearchHit hit : res.getHits().getHits()) {
            logger.info("输出结果：{}", hit.getSourceAsMap());
        }
    }
}
